package com.zhuhjay.service.system.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.benmanes.caffeine.cache.Cache;
import com.zhuhjay.common.base.enums.HttpCode;
import com.zhuhjay.common.base.exception.BasicBusinessException;
import com.zhuhjay.common.base.util.BeanBuilder;
import com.zhuhjay.common.web.model.vo.PageInfoVo;
import com.zhuhjay.service.system.mapper.SystemLogMapper;
import com.zhuhjay.service.system.model.dto.LogPageParamDto;
import com.zhuhjay.service.system.model.entity.SystemLog;
import com.zhuhjay.service.system.model.entity.SystemUser;
import com.zhuhjay.service.system.model.vo.LogVo;
import com.zhuhjay.service.system.service.SystemLogService;
import com.zhuhjay.service.system.service.SystemUserService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Zhuhjay
 * @since 2023-01-30
 */
@Service
public class SystemLogServiceImpl extends ServiceImpl<SystemLogMapper, SystemLog> implements SystemLogService {

    @Resource
    private SystemUserService userService;
    @Resource
    private Cache<Integer, Object> userInfoCache;

    @Override
    public PageInfoVo<LogVo> logPage(Integer pageNum, Integer pageSize, LogPageParamDto param) {
        Integer code = null;
        if (param.getCode() != null) {
            try {
                HttpCode httpCode = HttpCode.valueOf(param.getCode());
                code = httpCode.getCode();
            } catch (IllegalArgumentException e) {
                throw new BasicBusinessException("响应状态码不存在");
            }
        }
        LambdaQueryChainWrapper<SystemLog> lambdaQuery = this.lambdaQuery();
        // 如果对用户进行了模糊查询，那么需要先查询出用户id
        if (StrUtil.isNotBlank(param.getUsername())) {
            List<SystemUser> users = userService.lambdaQuery()
                    .like(SystemUser::getUsername, param.getUsername())
                    .list();
            Set<Integer> ids = new HashSet<>();
            // 存储模糊查询出来的用户id以及用户信息
            users.forEach(user -> {
                Integer id = user.getId();
                ids.add(id);
                userInfoCache.put(id, user);
            });
            lambdaQuery.in(SystemLog::getRequestUserId, ids);
        }
        Page<SystemLog> source = lambdaQuery
                .ge(param.getStartTime() != null, SystemLog::getCreateTime, param.getStartTime())
                .le(param.getEndTime() != null, SystemLog::getCreateTime, param.getEndTime())
                .eq(StrUtil.isNotBlank(param.getIp()), SystemLog::getRequestIp, param.getIp())
                .eq(param.getCode() != null, SystemLog::getResponseCode, code)
                .orderByDesc(SystemLog::getId)
                .page(Page.of(pageNum, pageSize));
        List<LogVo> collect = source.getRecords().stream()
                .map(log -> {
                    if (log.getRequestUserId() == null) {
                        return LogVo.of(log, null);
                    }
                    return LogVo.of(log, userService.getCreateUserByCaffeine(log.getRequestUserId()));
                })
                .collect(Collectors.toList());
        return BeanBuilder.builder(PageInfoVo<LogVo>::new)
                .with(PageInfoVo::setCurrent, source.getCurrent())
                .with(PageInfoVo::setSize, source.getSize())
                .with(PageInfoVo::setTotal, source.getTotal())
                .with(PageInfoVo::setRecords, collect)
                .build();
    }
}
